<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="zh-CN" />
<link href="style/css/manual-zip.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
<link href="style/css/manual-zip-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
<link href="style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" />
<title>从URL到文件系统的映射 － Apache 2.2 中文手册 [金步国]</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head>
<body id="manual-page">
<div id="page-header"><p class="menu"><a href="mod/index.html">模块索引</a> | <a href="mod/directives.html">指令索引</a> | <a href="faq/index.html">常见问题</a> | <a href="glossary.html">词汇表</a> | <a href="sitemap.html">站点导航</a></p><p class="apache">Apache HTTP Server 版本2.2</p><img alt="" src="images/feather.gif" /></div>
<div class="up"><a href="index.html"><img title="&lt;-" alt="&lt;-" src="images/left.gif" /></a></div>
<div id="path"><a href="https://www.apache.org/">Apache</a> &gt; <a href="https://httpd.apache.org/">HTTP Server</a> &gt; <a href="https://httpd.apache.org/docs/">文档</a> &gt; <a href="index.html">版本2.2</a></div>

<div id="translation-info">　　 <a href="translator_announcement.html#thanks">致谢</a> | 本篇译者：<a href="../../index.html">金步国</a>(<a href="../../index.html">作品集</a>) | 本页最后更新：2006年10月20日</div>
<div id="page-content"><div id="preamble"><h1>从URL到文件系统的映射</h1>


    <p>本文阐述Apache如何根据URL地址定位到文件在文件系统中的位置。</p>
  </div>
	<div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="related" id="related">相关模块和指令</a></h2>

<table border="1" cellpadding="0" cellspacing="0" bordercolor="#AAAAAA" class="related">
<tr><th>相关模块</th><th>相关指令</th></tr>
<tr><td><ul><li><code class="module"><a href="mod/mod_alias.html">mod_alias</a></code></li><li><code class="module"><a href="mod/mod_proxy.html">mod_proxy</a></code></li><li><code class="module"><a href="mod/mod_rewrite.html">mod_rewrite</a></code></li><li><code class="module"><a href="mod/mod_userdir.html">mod_userdir</a></code></li><li><code class="module"><a href="mod/mod_speling.html">mod_speling</a></code></li><li><code class="module"><a href="mod/mod_vhost_alias.html">mod_vhost_alias</a></code></li></ul></td><td><ul><li><code class="directive"><a href="mod/mod_alias.html#alias">Alias</a></code></li><li><code class="directive"><a href="mod/mod_alias.html#aliasmatch">AliasMatch</a></code></li><li><code class="directive"><a href="mod/mod_speling.html#checkspelling">CheckSpelling</a></code></li><li><code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code></li><li><code class="directive"><a href="mod/core.html#errordocument">ErrorDocument</a></code></li><li><code class="directive"><a href="mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="mod/mod_proxy.html#proxypass">ProxyPass</a></code></li><li><code class="directive"><a href="mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code></li><li><code class="directive"><a href="mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code></li><li><code class="directive"><a href="mod/mod_proxy.html#proxypassreversecookiepath">ProxyPassReverseCookiePath</a></code></li><li><code class="directive"><a href="mod/mod_alias.html#redirect">Redirect</a></code></li><li><code class="directive"><a href="mod/mod_alias.html#redirectmatch">RedirectMatch</a></code></li><li><code class="directive"><a href="mod/mod_rewrite.html#rewritecond">RewriteCond</a></code></li><li><code class="directive"><a href="mod/mod_rewrite.html#rewritematch">RewriteMatch</a></code></li><li><code class="directive"><a href="mod/mod_alias.html#scriptalias">ScriptAlias</a></code></li><li><code class="directive"><a href="mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code></li><li><code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code></li></ul></td></tr>
</table>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="documentroot" id="documentroot">DocumentRoot</a></h2>

    <p>Apache根据请求定位文件的默认操作是：取出URL路径(即URL中主机名和端口后面的部分)附加到由<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>指定的文件系统路径后面。这样就组成了在网上所看见的基本文件树结构。</p>

    <p>如果服务器有多个<a href="vhosts/index.html">虚拟主机</a>，则Apache会使用下述两种方法之一：使用每个虚拟主机自己的<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>来组成文件系统路径，或者使用由<code class="module"><a href="mod/mod_vhost_alias.html">mod_vhost_alias</a></code>提供的指令基于IP地址或主机名动态地定位文件。</p>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="outside" id="outside">DocumentRoot以外的文件</a></h2>

    <p>实际应用中，经常有必要允许网络对<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>以外的文件进行访问。对此，Apache提供了多种方法，在Unix系统中，可以在文件系统的<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>目录下放置符号连接以访问其外部文件，考虑到安全问题，这种方法仅在相应目录的<code class="directive"><a href="mod/core.html#options">Options</a></code>指令中设置了<code>FollowSymLinks</code>或<code>SymLinksIfOwnerMatch</code>时才有效。</p>

    <p>另外，使用<code class="directive"><a href="mod/mod_alias.html#alias">Alias</a></code>指令可以将文件系统的任何部分映射到网络空间中。例如，这个命令</p>

<div class="example"><p><code>Alias /docs /var/web</code></p></div>

    <p>可以把URL <code>http://www.example.com/docs/dir/file.html</code>映射为<code>/var/web/dir/file.html</code> 。<code class="directive"><a href="mod/mod_alias.html#scriptalias">ScriptAlias</a></code>指令功能相似，而且使所有目标路径下的所有文件被视为<a class="glossarylink" href="glossary.html#cgi" title="see glossary">CGI</a>脚本。</p>

    <p><code class="directive"><a href="mod/mod_alias.html#aliasmatch">AliasMatch</a></code>和<code class="directive"><a href="mod/mod_alias.html#scriptaliasmatch">ScriptAliasMatch</a></code>指令可以实现基于<a class="glossarylink" href="glossary.html#regex" title="see glossary">正则表达式</a>的匹配和替换，以提供更大的灵活性。例如：</p>

<div class="example"><p><code>ScriptAliasMatch ^/~([a-zA-Z0-9]+)/cgi-bin/(.+) /home/$1/cgi-bin/$2</code></p></div>

    <p>上述命令可以将<code>http://example.com/~user/cgi-bin/script.cgi</code> 映射到<code>/home/user/cgi-bin/script.cgi</code> ，并视之为CGI脚本。</p>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="user" id="user">用户目录</a></h2>

    <p>在Unix系统中，一个特定用户"<em>user</em>"的主目录通常是"<code>~user/</code>"模块<code class="module"><a href="mod/mod_userdir.html">mod_userdir</a></code>在网络上沿用了这个概念，允许使用URL访问位于各用户主目录下的文件，例如：</p>

<div class="example"><p><code>http://www.example.com/~user/file.html</code></p></div>

    <p>出于安全原因，不应该给予网络用户直接操作主目录的权限，而应该在用户主目录下新建一个目录，把网络文件放在这个新建的目录中，并用<code class="directive"><a href="mod/mod_userdir.html#userdir">UserDir</a></code>指令告诉服务器。缺省的用户目录设置是"<code>Userdir public_html</code>"，因此，上述例子中的URL会映射到<code>/home/user/public_html/file.html</code> ，其中<code>/home/user/</code> 是<code>/etc/passwd</code>指定的用户主目录。</p>

    <p>当<code>/etc/passwd</code>没有指定主目录，那就要用到<code>Userdir</code>指令的另几种形式。</p>

    <p>有些人觉得符号"~"(时常会被编码为<code>%7e</code>)很别扭，希望用其他形式来表达用户目录。虽然模块<code class="module"><a href="mod/mod_userdir.html">mod_userdir</a></code>并不支持，但是，如果合理规划服务器上的用户目录，则还是有可能用<code class="directive"><a href="mod/mod_alias.html#aliasmatch">AliasMatch</a></code>指令来达到这个目的。例如，如果希望将<code>http://www.example.com/upages/user/file.html</code>映射到<code>/home/user/public_html/file.html</code> ，可以这样使用<code>AliasMatch</code>指令：</p>

<div class="example"><p><code>AliasMatch ^/upages/([a-zA-Z0-9]+)/?(.*) /home/$1/public_html/$2</code></p></div>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="redirect" id="redirect">URL重定向</a></h2>

    <p>上述指令都指示Apache返回给客户文件系统的某个特定内容，但是有时候，需要通知客户其请求的内容位于其他URL，并使客户产生新的对其他URL的请求，这种机制称为<em>重定向(redirection)</em>，可以用<code class="directive"><a href="mod/mod_alias.html#redirect">Redirect</a></code>指令实现。例如：如果<code class="directive"><a href="mod/core.html#documentroot">DocumentRoot</a></code>的目录<code>/foo/</code>被转移到了<code>/bar/</code> ，则可以这样引导客户访问新的位置：</p>

<div class="example"><p><code>Redirect permanent /foo/ http://www.example.com/bar/</code></p></div>

    <p>这个命令重定向任何以<code>/foo/</code>开头的URL路径到位于同一个服务器<code>www.example.com</code>的<code>/bar/</code> 。当然，可以重定向到任何其它服务器，而不仅仅是原来的那个。</p>

    <p>Apache还提供了<code class="directive"><a href="mod/mod_alias.html#redirectmatch">RedirectMatch</a></code>指令来解决复杂的重定向问题。例如，要重定向对站点主页的请求到其他站点，而保留其他所有请求，可以这样配置：</p>

<div class="example"><p><code>RedirectMatch permanent ^/$ http://www.example.com/startpage.html</code></p></div>

    <p>另一种方法是，暂时地重定向站点的所有页面到一个特定页面，如：</p>

<div class="example"><p><code>RedirectMatch temp .*  http://othersite.example.com/startpage.html</code></p></div>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="proxy" id="proxy">反向代理</a></h2>

<p>Apache还允许将远程文档纳入本地服务器的网络空间中，因为Web服务器扮演一个代理服务器的角色(从远程服务器取得文档并返回给客户)，所以这种机制被称为<em>反向代理(reverse proxying)</em>，不同于标准代理的是，在客户看来，他请求的文档似乎原本就位于这个反向代理服务器上。</p>

<p>下例演示了当客户请求位于<code>/foo/</code>目录下的文档时，服务器从<code>internal.example.com</code>的<code>/bar/</code>目录下取回文档并返回给客户，似乎文档原本就在本地服务器上：</p>

<div class="example"><p><code>
ProxyPass /foo/ http://internal.example.com/bar/<br />
ProxyPassReverse /foo/ http://internal.example.com/bar/
ProxyPassReverseCookieDomain internal.example.com public.example.com
ProxyPassReverseCookiePath /foo/ /bar/
</code></p></div>

<p><code class="directive"><a href="mod/mod_proxy.html#proxypass">ProxyPass</a></code>指令使服务器正确地取回文档，同时，<code class="directive"><a href="mod/mod_proxy.html#proxypassreverse">ProxyPassReverse</a></code>指令改变了起始于<code>internal.example.com</code>的请求，使之指向本地服务器上的目录。同样，<code class="directive"><a href="mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>和<code class="directive"><a href="mod/mod_proxy.html#proxypassreversecookiedomain">ProxyPassReverseCookieDomain</a></code>指令将会改变后端服务器设置的cookie 。</p>
<p>需要注意的很重要的一点是，被取回的文档中的连接是不会被改写的，因此，文档中的所有绝对路径连接会突破代理机制而直接从<code>internal.example.com</code>取得。一个第三方模块<a href="http://apache.webthing.com/mod_proxy_html/">mod_proxy_html</a>可以用于重写HTML和XHTML连接。</p>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="rewrite" id="rewrite">URL重写引擎</a></h2>

    <p><code class="module"><a href="mod/mod_rewrite.html">mod_rewrite</a></code>模块提供了更强大的URL重写引擎，可以根据请求中诸如浏览器类型、源IP地址等特征来决定最终提交给客户的内容，还可以使用外部数据库或程序来决定如何处理一个请求，并可以执行上述的所有三种映射：内部重定向(aliases)、外部重定向、代理。许多实用程序都用到了这个模块，详细论述参见：<a href="rewrite/rewrite_guide.html">URL重写指南</a>。</p>
</div><div class="top"><a href="urlmapping.html#page-header"><img alt="top" src="images/up.gif" /></a></div>
<div class="section">
<h2><a name="notfound" id="notfound">File Not Found</a></h2>

    <p>从URL到文件系统的匹配失败是不可避免的，其产生原因有多种。有时是文档被转移了，对此最好是用<a href="urlmapping.html#redirect">URL重定向</a>来引导用户访问新的位置，这样，虽然资源已经转移到新的位置，但是原来的书签和连接仍然有效。</p>

    <p>另一种常见的原因是浏览器地址栏或者HTML连接中的URL被拼写错了，Apache提供了<code class="module"><a href="mod/mod_speling.html">mod_speling</a></code>模块来帮助解决这个问题，它会接管"File Not Found"错误并查找相似文件，如果找到了唯一的一个，则会重定向到这个文件，如果不止一个，则会列一张表反馈给用户。</p>

    <p><code class="module"><a href="mod/mod_speling.html">mod_speling</a></code>的一个很有用的特性是，它可以忽略大小写查找文件，对不注意URL大小写的用户和unix文件系统尤为实用。但是，纠正偶然的URL错误会给服务器带来额外的负担，因为每次"不正确"的请求都将引发URL重定向和来自客户的新请求。</p>

    <p>如果所有的努力都失败了，Apache会返回一个出错信息页面，其状态码为"404"(文件没找到)，其页面内容取决于<code class="directive"><a href="mod/core.html#errordocument">ErrorDocument</a></code>指令，并可以灵活地自定义其形式，详见：<a href="custom-error.html">自定义错误响应</a>。</p>
</div></div>
<div id="footer">
<p class="apache">本文允许自由的转载、引用、再分发，但必须保留译者署名并注明出处；详见：<a href="translator_announcement.html#announcement">版权声明</a>。</p>
<p class="menu"><a href="mod/index.html">模块索引</a> | <a href="mod/directives.html">指令索引</a> | <a href="faq/index.html">常见问题</a> | <a href="glossary.html">词汇表</a> | <a href="sitemap.html">站点导航</a></p></div>
</body></html>
